
/* 
 * com.ctvit.framework.web.listener.ContextLoadListener.java Create on Apr 18, 2008 3:53:29 PM By Q-Wang 
 * $HEAD$
 */
package com.ctvit.framework.web.context;

import java.lang.reflect.Field;
import java.util.Date;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.DoubleConverter;
import org.apache.commons.beanutils.converters.FloatConverter;
import org.apache.commons.beanutils.converters.IntegerConverter;
import org.apache.commons.beanutils.converters.LongConverter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jbpm.graph.exe.ExecutionContext;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.ctvit.framework.util.DateConverter;
import com.ibatis.sqlmap.engine.mapping.result.ResultObjectFactoryUtil;

/**
 * ServletContext Life Cycle Listener.
 * 
 * @see ContextLoaderListener
 * @see ServletContextListener
 * @see ContextHolder
 * @author Q-Wang
 */
public class ContextLoadListener extends ContextLoaderListener implements ServletContextListener {

	protected final Log log = LogFactory.getLog(ContextLoadListener.class);

	protected final boolean isDebugEnabled = log.isDebugEnabled();

	protected ServletContext servletContext;

	protected ApplicationContext applicationContext;

	/**
	 * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)
	 */
	public void contextDestroyed(ServletContextEvent event) {
		super.contextDestroyed(event);
		// Fixed com.ibatis.sqlmap.engine.mapping.result.ResultObjectFactoryUtil CL memory leak.
		try {
			Field field = ResultObjectFactoryUtil.class.getDeclaredField("factorySettings");
			field.setAccessible(true);
			log.info("Release Ibatis ResultObjectFactoryUtil CLML success.");
		} catch (Exception e) {
		}
		ContextHolder.getInstance().shutdown();
		log.debug("ContextLoadListener: Context Destroyed.");
		// // Release Commons Logging Cache, (fix commons-logging classLoader memory leak)
		LogFactory.release(Thread.currentThread().getContextClassLoader());
		System.gc(); // Call gc for clean heapdump and check memory leak.
	}

	/**
	 * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
	 */
	public void contextInitialized(ServletContextEvent event) {
		if (isDebugEnabled) {
			log.debug("ContextLoadListener: Context Loading...");
		}
		super.contextInitialized(event);
		servletContext = event.getServletContext();
		applicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
		doInitialized();
		if (isDebugEnabled) {
			log.debug("ContextLoadListener: Context Initialize Success.");
		}
	}

	/**
	 * 站台初始化代码.
	 */
	protected void doInitialized() {
		registerConverters();
		registerServletContext();
	}

	/**
	 * 注册类型转换器.
	 */
	protected void registerConverters() {
		ConvertUtils.register(new IntegerConverter(null), Integer.class);
		ConvertUtils.register(new LongConverter(null), Long.class);
		ConvertUtils.register(new FloatConverter(null), Float.class);
		ConvertUtils.register(new DoubleConverter(null), Double.class);
		ConvertUtils.register(new DateConverter("yyyy-MM-dd"), Date.class);
	}

	/**
	 * 设置ContextHolder.
	 */
	protected void registerServletContext() {
		ContextHolder.getInstance().setServletContext(servletContext);
		ContextHolder.getInstance().setApplicationContext(applicationContext);
	}
}
